package orm

import (
	"fmt"
	"math/rand"
	"reflect"
	"regexp"
	"strings"
	"time"
)

/**
 * 解决sqlx不支持IN和数组参数的问题
 */

// 替换数组对应的占位符(`?`=>`?,?,...`)，从而允许直接使用IN子句
func ReplacePlaceHolder(query string, argv ...interface{}) (string, []interface{}) {
	part := strings.Split(query, "?")
	if len(part) != len(argv)+1 {
		panic("占位符和参数数量不同")
	}
	_query := part[0]
	_argv := make([]interface{}, 0)
	for i, a := range argv {
		k := reflect.TypeOf(a).Kind()
		if k == reflect.Slice || k == reflect.Array {
			v := reflect.ValueOf(a)
			for i:=0; i<v.Len(); i++{
				_argv = append(_argv, v.Index(i).Interface())
			}
			if l := v.Len(); l!= 0 {
				_query += "?" + strings.Repeat(" ,?", l-1)
			} else {
				if prev := strings.TrimSuffix(_query, " "); strings.HasSuffix(prev, ",") {
					_query = strings.TrimSuffix(prev, ",")
				} else if next := strings.TrimPrefix(part[i+1], " "); strings.HasPrefix(next, ",") {
					part[i+1] = strings.TrimPrefix(next, ",")
				} else {
					// 找到当前的条件表达式，并判断是不是IN语句,如果是则替换成false
					re, _ := regexp.Compile(`(?i)( and | or | where | having | on | && | \|\| )`)
					is := re.FindAllStringIndex(_query, -1)
					if is != nil {
						loc := is[len(is)-1]
						re2, _ := regexp.Compile(`(?i)in[ ]*\([ ]*$`)
						if re2.MatchString(_query[loc[1]:]) && strings.HasPrefix(next, ")") {
							_query = _query[:loc[1]] + " false"
							part[i+1] = strings.TrimPrefix(next, ")")
						}
					} else {
						// 最后的补救措施，设置一个不会被匹配到的随机字符串
						rand.Seed(time.Now().UnixNano())
						_query += fmt.Sprintf("'field value list is empty, code:%d'", rand.Intn(999999))
					}
				}
			}
		} else {
			_argv = append(_argv, a)
			_query += "?"
		}
		_query += part[i+1]
	}
	return _query, _argv
}